<?php

declare(strict_types=1);

namespace app;

use think\App;
use think\exception\ValidateException;
use think\Validate;

use think\facade\Env;
use think\cache\driver\Redis;

use think\facade\Request;
use think\facade\Db;
use think\facade\View;
use think\facade\Session;
use think\facade\Cookie;
use Hashids\Hashids;

use app\model\{
  User as UserModel,
};

/**
 * 控制器基础类
 */
abstract class AuthController
{
  /**
   * Request实例
   * @var \think\Request
   */
  protected $request;

  /**
   * 应用实例
   * @var \think\App
   */
  protected $app;

  /**
   * 是否批量验证
   * @var bool
   */
  protected $batchValidate = false;

  /**
   * 控制器中间件
   * @var array
   */
  protected $middleware = [];

  /**
   * 构造方法
   * @access public
   * @param  App  $app  应用对象
   */
  public function __construct(App $app)
  {
    $this->app     = $app;
    $this->request = $this->app->request;

    // 初始化
    $this->initialize();
  }

  // 初始化
  protected function initialize()
  {
    $this->redisInit(); // Redis初始化
  }

  /**
   * 验证数据
   * @access protected
   * @param  array        $data     数据
   * @param  string|array $validate 验证器名或者验证规则数组
   * @param  array        $message  提示信息
   * @param  bool         $batch    是否批量验证
   * @return array|string|true
   * @throws ValidateException
   */
  protected function validate(array $data, $validate, array $message = [], bool $batch = false)
  {
    if (is_array($validate)) {
      $v = new Validate();
      $v->rule($validate);
    } else {
      if (strpos($validate, '.')) {
        // 支持场景
        [$validate, $scene] = explode('.', $validate);
      }
      $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
      $v     = new $class();
      if (!empty($scene)) {
        $v->scene($scene);
      }
    }

    $v->message($message);

    // 是否批量验证
    if ($batch || $this->batchValidate) {
      $v->batch(true);
    }

    return $v->failException(true)->check($data);
  }

  use \liliuwei\think\Jump;
  ######################################################################################################################





  ######################################################################################################################
  # Redis
  ######################################################################################################################

  /**
   * Redis
   * @var \think\cache\driver\Redis
   */
  protected $redis;

  // Redis初始化
  protected function redisInit()
  {
    $this->redis = new Redis();
    $this->redis->connect(Env::get('redis.hostname', '127.0.0.1'), Env::get('redis.port', 3306));
    $this->redis->auth(Env::get('redis.password', ''));
    $this->redis->select(Env::get('redis.select', 0));
  }
  ######################################################################################################################





  ######################################################################################################################
  # 基础前置控制器
  ######################################################################################################################

  // 编码文章标识KEY
  protected function setArticleKey($id)
  {
    $Hashids = new Hashids('soyulsmida', 7);
    return $Hashids->encode($id);
  }

  // 解码文章标识KEY
  protected function getArticleKey($key)
  {
    $Hashids = new Hashids('soyulsmida', 7);
    $result = $Hashids->decode($key);
    return count($result) ? $result[0] : false;
  }















  /*
 * 游客注册登录
 * 根据用户昵称、邮箱、网址进行游客注册
 */
  protected function t_login($nick, $email, $website)
  {
    if (empty($nick)) {
      return ['state' => 'error', 'info' => '昵称不能为空'];
    } else if (!preg_match('/^[\x{4e00}-\x{9fa5}A-Za-z0-9]+$/u', $nick)) {
      return ['state' => 'error', 'info' => '昵称只能为汉字，英文字母或数字'];
    }

    $result1 = UserModel::where('nick', $nick)->count();
    $result2 = Db::name('user_tourist')->where('nick', $nick)->count();
    if (!$result1 && !$result2) {
      # 昵称验证成功，准备写入数据表
      $BR = $this->request->requestInfo;
      $resid = Db::name('user_tourist')->insertGetId(['nick' => $nick, 'email' => $email, 'website' => $website, 'user_agent' => $BR['user_agent']]);
      if ($resid) {
        $Hashids = new Hashids('choalovetourist', 5);
        $uid = $Hashids->encode($resid);
        Db::name('user_tourist')->where('id', $resid)->update(['uid' => $uid]);

        $BR['request_code'] = 'DRy';
        $BR['user_id'] = $uid;
        Db::name('website_request')->insert($BR);

        Cookie::forever('touristuid', $uid);
        Cookie::forever('touristkey', md5($BR['user_agent'] . 'choaloveyou'));
        return ['state' => 'success', 'info' => $uid];
      } else {
        return ['state' => 'error', 'info' => '不知道为什么就登录失败了，再试一次吧'];
      }
    } else {
      return ['state' => 'error', 'info' => '您输入的昵称已经被占用了，换个试试吧'];
    }
  }
  /*
 * 修改游客信息
 * 根据用户昵称、邮箱、网址进行游客注册
 */
  protected function t_update($nick, $email, $website, $uid)
  {
    if (empty($nick)) {
      return ['state' => 'error', 'info' => '昵称不能为空'];
    } else if (!preg_match('/^[\x{4e00}-\x{9fa5}A-Za-z0-9]+$/u', $nick)) {
      return ['state' => 'error', 'info' => '昵称只能为汉字，英文字母或数字'];
    }

    $result1 = Db::name('user')->where('nick', $nick)->count();
    $result2 = Db::name('user_tourist')->where('uid', '<>', $uid)->where('nick', $nick)->count();
    if (!$result1 && !$result2) {
      $resid = Db::name('user_tourist')->where('uid', $uid)->update(['nick' => $nick, 'email' => $email, 'website' => $website]);
      return ['state' => 'success', 'info' => $uid];
    } else {
      return ['state' => 'error', 'info' => '您输入的昵称已经被占用了，换个试试吧'];
    }
  }
}
